<template>
  <div class="create-china-id-card">

    <div class="container">
      <el-form label-position="top">
        <el-form-item label="出生日期">
          <el-select v-model="field.year" placeholder="选择年份" style="width: 120px;" filterable>
            <el-option v-for="item in years" :key="item.value" :label="item.label" :value="item.value"></el-option>
          </el-select>
          <el-select v-model="field.month" placeholder="选择月份" style="width: 120px;" filterable>
            <el-option v-for="item in months" :key="item.value" :label="item.label" :value="item.value"></el-option>
          </el-select>
          <el-select v-model="field.day" placeholder="选择日" style="width:120px;" filterable>
            <el-option v-for="item in days" :key="item.value" :label="item.label" :value="item.value"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="身份证归属地">
          <el-select v-model="field.province" placeholder='请选择' style="width: 160px" :disabled="step < 1" filterable>
            <el-option v-for="item in provinces" :key="item.value" :label="item.label" :value="item.value"></el-option>
          </el-select>
          <el-select v-model="field.city" placeholder='请选择' style="width: 160px" :disabled="step < 2" filterable>
            <el-option v-for="item in citys" :key="item.value" :label="item.label" :value="item.value"></el-option>
          </el-select>
          <el-select v-model="field.area" placeholder='请选择' style="width: 160px" :disabled="step < 3" filterable>
            <el-option v-for="item in areas" :key="item.value" :label="item.label" :value="item.value"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="选择性别">
          <el-radio v-model="field.sex" :label="item" v-for="(item,i) in sexs" :value="item" :key="i"></el-radio>
        </el-form-item>
        <el-form-item label="末尾是否为X">
          <el-radio v-model="field.isX" :label="item" v-for="(item,i) in isXarr" :value="item" :key="i"></el-radio>
        </el-form-item>
        <el-form-item label="安全模式" v-show="false">
          <el-switch v-model="safe" active-color="#13ce66" inactive-color="#ff4949"></el-switch>
          <span style="margin-left: 15px">
						<el-button type="text" @click="showSafeMode = true">什么是安全模式?</el-button>
					</span>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onCreate">自定义生成</el-button>
          <el-button type="primary" @click="randomCreate">随机生成</el-button>
        </el-form-item>
        <el-form-item>
          {{res.title}}
          <br>

          <div class="res-item">
            姓名:&nbsp;{{res.name}}
            <el-button type="primary" class="res-button" @click="handleCopy(res.name, $event)">
              复制姓名
            </el-button>
          </div>

          <div class="res-item">
            身份证号:&nbsp;{{res.id}}
            <el-button type="primary" class="res-button" @click="handleCopy(res.id, $event)">
              复制身份证号
            </el-button>
          </div>

          <div class="res-item">
            手机号:&nbsp;{{res.phone}}
            <el-button type="primary" class="res-button" @click="handleCopy(res.phone, $event)">
              复制手机号
            </el-button>
          </div>

          <div class="res-item">
            银行卡号:&nbsp;{{res.bank}}
            <el-button type="primary" class="res-button" @click="handleCopy(res.bank, $event)">
              复制银行卡号
            </el-button>
          </div>

        </el-form-item>
      </el-form>
    </div>

    <el-dialog title="什么是安全模式" :visible.sync="showSafeMode" width="480px">
      <p>当你开启了安全模式后, 我们会按照更加严谨的事实情况来生成身份证号码, 譬如第一代身份证最早诞生于1984年4月6号启用的, 长度为15位, 2004年3月29号第二代居民身份证开始发放, 即安全模式下,
        无法创建小于第一代身份证启用时间的身份证号码, 同时身份证算法和位数将严格按照年代来生成</p>
      <p>如果不开启安全模式, 那么你将可以任意组合年月日, 我们允许您从1000年~至今, 且全部统一为第二代身份证的18位号码!</p>
      <template slot="footer">
        <el-button type="primary" @click="showSafeMode = false">我知道了</el-button>
      </template>
    </el-dialog>

  </div>
</template>

<script>
  import pca from "~/db/pca";
  import mock from "mockjs";
  import validator from 'validator';
  import moment from "moment";
  import clip from '../utils/clipboard' // use clipboard directly
  import clipboard from '../directive/clipboard/index.js' // use clipboard by v-directive

  const {
    Random
  } = mock;

  export default {
    metaInfo: {
      title: "身份信息在线生成"
    },
    directives: {
      clipboard
    },
    data () {
      return {
        safe: true,
        showSafeMode: false,
        field: {},
        years: [],
        months: [],
        days: [],
        provinces: [],
        citys: [],
        areas: [],
        sexs: ["男", "女"],
        isXarr: [true, false],
        step: 0,
        res: {
          title: '',
          id: '',
          name: '',
          bank: '',
          phone: '',
        }
      }
    },
    computed: {
      fieldYear: function () {
        const _this = this;

        return _this.field.year;
      },
      fieldMonth: function () {
        const _this = this;

        return _this.field.month;
      },
      fieldProvince: function () {
        const _this = this;

        return _this.field.province;
      },
      fieldCity: function () {
        const _this = this;

        return _this.field.city;
      },
      fieldArea: function () {
        const _this = this;
        // console.log(_this.field.area);
        return _this.field.area;
      }
    },
    watch: {
      safe: function (open) {
        const _this = this;

        if (open) {
          //_this.$message.success("您开启了安全模式");
          _this.initSafe();
        } else {
          //_this.$message.error("您关闭了安全模式");
          _this.initNoSafe()
        }
      },
      fieldYear: function (year) {
        const _this = this

        if (year) {
          _this.initMonths().then(function () {
            if (_this.safe) {
              if (_this.field.year == '1984') {
                _this.field.month = '04';
              } else {
                _this.field.month = '01';
              }
            }
          })
        }
      },
      fieldMonth: function (month) {
        const _this = this;

        if (month) {
          let year = _this.field.year;
          let isRunNian = ((year % 4 == 0 && year % 400 == 0) || year % 100 != 0) ? true : false;
          let days = [];

          if (isRunNian) {
            days = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
          } else {
            days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
          }
          _this.initDays(days[month - 1]).then(function () {
            if (_this.safe) {
              if (_this.field.year == '1984' && _this.field.month == '04') {
                _this.field.day = "06";
              } else {
                _this.field.day = "01";
              }
            }
          })
        }
      },
      fieldProvince: function (province) {
        const _this = this;

        let citys = pca[province];

        if (citys) {
          let data = [];
          Object.keys(citys).forEach(function (id) {
            data.push({
              label: citys[id],
              value: id.toString()
            })
          })

          _this.step = 2;
          _this.field.city = '';
          _this.field.area = '';
          _this.citys = data;
          _this.areas = [];
        }
      },
      fieldCity: function (city) {
        const _this = this;

        let areas = pca[city];

        if (areas) {
          let data = [];
          Object.keys(areas).forEach(function (id) {
            data.push({
              label: areas[id],
              value: id.toString()
            })
          })

          _this.step = 3;
          _this.field.area = '';
          _this.areas = data;
        }
      },
      fieldArea: function (area) {
        // console.log(area);
        const _this = this;
        _this.field.area = area;

        //let areas = pca[area];

        // if(areas) {
        // 	let data = [];
        // 	Object.keys(areas).forEach(function(id) {
        // 		data.push({
        // 			label: areas[id],
        // 			value: id.toString()
        // 		})
        // 	})

        // 	_this.step = 3;
        // 	_this.field.area = '';
        // 	_this.areas = data;
        // }
      }
    },
    created () {
      const _this = this;
      _this.initNoSafe();
    },
    mounted () {
      const _this = this;
      _this.randomCreate();
    },
    methods: {
      // 生成从minNum到maxNum的随机数
      randomNum (minNum, maxNum) {
        switch (arguments.length) {
          case 1:
            return parseInt(Math.random() * minNum + 1, 10);
            break;
          case 2:
            return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
            break;
          default:
            return 0;
            break;
        }
      },
      randomCreate () {
        const _this = this;

        let sexArr = ['男', '女'];
        let sexRandomVal = Math.round(Math.random());
        let sexRandomRes = sexArr[sexRandomVal];

        let isXArr = [true, false];
        let isXRandomVal = Math.round(Math.random());
        let isXRandomRes = isXArr[isXRandomVal];

        let yearRandomRes = _this.randomNum(1990, 2019);

        let monthRandomRes = _this.randomNum(1, 12);
        if (monthRandomRes < 10) {
          monthRandomRes = '' + monthRandomRes + '';
          monthRandomRes = '0' + monthRandomRes;
        }

        let dayRandomRes = _this.randomNum(1, 28);
        if (dayRandomRes < 10) {
          dayRandomRes = '' + dayRandomRes + '';
          dayRandomRes = '0' + dayRandomRes;
        }

        _this.field = {
          year: '' + yearRandomRes + '',
          month: '' + monthRandomRes + '',
          day: '' + dayRandomRes + '',
          province: '370000',
          city: '370100',
          area: '370102',
          sex: sexRandomRes,
          isX: isXRandomRes
        };

        _this.onCreate();
      },
      onCreate () {
        const _this = this;

        // console.log(_this.field);
        let field = Object.assign({}, _this.field);

        if (validator.isEmpty(field.year)) {
          _this.$message.warning("请选择年份");
          return;
        }

        if (validator.isEmpty(field.month)) {
          _this.$message.warning("请选择月份");
          return;
        }

        if (validator.isEmpty(field.day)) {
          _this.$message.warning("请选择具体日期");
          return;
        }

        if (validator.isEmpty(field.province)) {
          _this.$message.warning("您必须要选择省");
          return;
        }

        if (validator.isEmpty(field.city)) {
          _this.$message.warning("您必须要选择市");
          return;
        }

        if (validator.isEmpty(field.area)) {
          _this.$message.warning("您必须要选择区");
          return;
        }

        if (_this.safe) {
          let minTime = new Date('1984-04-06 00:00:00').getTime();
          let maxTime = new Date('2004-03-29 00:00:00').getTime();
          let nowTime = Date.now();
          let time = new Date([field.year, field.month, field.day].join("-")).getTime();

          if (time < minTime || time > nowTime) {
            _this.$message.error("不合法的出生日期");
          } else {
            if (time >= minTime && time <= maxTime) {
              let id = _this.card1st();
              let name = Random.cname();
              // _this.$notify({
              // 	title: '第一代身份证号码',
              // 	dangerouslyUseHTMLString: true,
              // 	message: `<p><b>姓名: </b>${name}</p><p><b>身份证号: </b>${id}</p>`,
              // 	duration: 1000 * 10,
              // 	type: 'success'
              // });
              _this.res = {
                title: '第一代身份证号码',
                name: name,
                id: id,
              }
            }

            if (time > maxTime && time < nowTime) {
              let res = _this.card2st()
              let id = res.idNo;
              let last = res.last;
              console.log('一')
              console.log('结果里的：' + id)
              console.log('结果里的：' + last)
              if (last !== 'X' && this.field.isX) {
                let that = this
                setTimeout(() => {
                  that.onCreate()
                }, 0)
                return false
              } else {
                this.$forceUpdate()
              }
              let name = Random.cname();
              // _this.$notify({
              // 	title: '第二代身份证号码',
              // 	dangerouslyUseHTMLString: true,
              // 	message: `<p><b>姓名: </b>${name}</p><p><b>身份证号: </b>${id}</p>`,
              // 	duration: 1000 * 10,
              // 	type: 'success'
              // });
              _this.res = {
                title: '第二代身份证号码',
                name: name,
                id: id,
              }
            }
          }
        } else {
          let res = _this.card2st()
          let id = res.idNo;
          let last = res.last;
          console.log('二')
          console.log('结果里的：' + id)
          console.log('结果里的：' + last)
          if (last !== 'X' && this.field.isX) {
            let that = this
            setTimeout(() => {
              that.onCreate()
            }, 0)
            return false
          } else {
            this.$forceUpdate()
          }
          let name = Random.cname();
          // _this.$notify({
          // 	title: '第二代身份证号码',
          // 	dangerouslyUseHTMLString: true,
          // 	message: `<p><b>姓名: </b>${name}</p><p><b>身份证号: </b>${id}</p>`,
          // 	duration: 1000 * 10,
          // 	type: 'success'
          // });
          _this.res = {
            title: '第二代身份证号码',
            name: name,
            id: id,
          }
        }

        this.getBankAccount();
        this.getMoble();
      },
      onDropdownItem (cmd) {
        const _this = this;

        switch (cmd) {
          default:
            _this.$message.warning("开发中..");
            break;
        }
      },
      card1st () {
        const _this = this;
        let field = Object.assign({}, _this.field);

        let code;
        if (field.area) {
          code = field.area;
        } else if (field.city) {
          code = field.city;
        } else if (field.province) {
          code = field.province;
        }

        let year = field.year.substring(2);
        let month = field.month;
        let day = field.day;
        let random = Math.floor(Math.random() * 899 + 100);
        let id = `${code}${year}${month}${day}${random}`;

        return id;
      },
      card2st () {
        const _this = this;
        let field = Object.assign({}, _this.field);

        let code;
        if (field.area) {
          code = field.area;
        } else if (field.city) {
          code = field.city;
        } else if (field.province) {
          code = field.province;
        }

        // 前17位
        let year = field.year;
        let month = field.month;
        let day = field.day;
        let random = Math.floor(Math.random() * 899 + 100);
        let id = `${code}${year}${month}${day}${random}`;

        // 最后一位
        let mi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
        let mo = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
        let sum = 0;
        for (let i = 0; i < id.length; i++) {
          sum += parseInt(id.charAt(i)) * mi[i];
        }
        let moIndex = sum % 11;
        let last = mo[moIndex];
        console.log('方法里的：' + `${id}${last}`)

        this.$forceUpdate()
        return {
          idNo: `${id}${last}`,
          last: `${last}`
        }
        /* let that = this
        if (`${last}` !== 'X') {
          console.log('不为X')
          setTimeout(() => {
            that.card2st()
            that.$forceUpdate()
          }, 0)
        } else {
          console.log('为X')
          this.$forceUpdate()
          return `${id}${last}`;
        } */

      },
      initSafe () {
        const _this = this;

        let tasks = [];
        tasks.push(_this.initYears());
        tasks.push(_this.initProvinces());

        Promise.all(tasks).then(function () {
          _this.field = {
            year: '',
            month: '',
            day: '',
            province: '',
            city: '',
            area: '',
            sex: '男',
            isX: false
          }

          _this.safe = true;
        });
      },
      initNoSafe () {
        const _this = this;

        let tasks = [];
        tasks.push(_this.initYears(1900));
        tasks.push(_this.initProvinces());

        Promise.all(tasks).then(function () {
          _this.field = {
            year: '1990',
            month: '01',
            day: '02',
            province: '370000',
            city: '370100',
            area: '370102',
            sex: '男',
            isX: false
          }

          // console.log(_this.field);
          _this.safe = false;
        });

        _this.field = {
          year: '1990',
          month: '01',
          day: '02',
          province: '370000',
          city: '370100',
          area: '370102',
          sex: '男',
          isX: false
        }

      },
      initProvinces () {
        const _this = this;

        return new Promise(function (resolve, reject) {
          try {
            let provinces = Object.assign({}, pca["86"]);

            let data = [];
            Object.keys(provinces).forEach(function (id) {
              data.push({
                label: provinces[id],
                value: id.toString()
              })
            })

            _this.step = 1;
            _this.provinces = data;
            // console.log(data);

            resolve(data);
          } catch (e) {
            reject(e);
          }
        })
      },
      initYears (min = 1984, max = new Date().getFullYear()) {
        const _this = this;

        return new Promise(function (resolve, reject) {
          try {
            let start = min;
            let end = max;

            let data = [];
            for (let i = start; i < end; i++) {
              data.push({
                label: `${i}年`,
                value: i.toString()
              })
            }
            _this.years = data;

            resolve(data);
          } catch (e) {
            reject(e);
          }
        })
      },
      initMonths (min = 1, max = 12) {
        const _this = this;

        return new Promise(function (resolve, reject) {
          try {
            let start, end;
            start = min;
            end = max;

            if (_this.safe) {
              if (_this.field.year == 1984) {
                start = 4;
              }
            }

            let data = [];
            for (let i = start; i <= end; i++) {
              data.push({
                label: `${i}月`,
                value: i < 10 ? '0' + i : i.toString()
              })
            }
            _this.months = data;

            resolve(data);
          } catch (e) {
            reject(e);
          }
        })
      },
      initDays (max = 31) {
        const _this = this;

        return new Promise(function (resolve, reject) {
          try {
            let start, end;
            start = 1;
            end = max;

            if (_this.safe) {
              if (_this.field.year == 1984 && _this.field.month == 4) {
                start = 6;
              }
            }

            let data = [];
            for (let i = start; i <= end; i++) {
              data.push({
                label: `${i}日`,
                value: i < 10 ? '0' + i : i.toString()
              })
            }
            _this.days = data;

            resolve(data);
          } catch (e) {
            reject(e);
          }
        })
      },
      // 生成随机银行卡号
      getBankAccount () {
        var bank_no = '0102';
        var prefix = "";
        switch (bank_no) {
          case "0102":
            prefix = "622202";
            break;
          case "0103":
            prefix = "622848";
            break;
          case "0105":
            prefix = "622700";
            break;
          case "0301":
            prefix = "622262";
            break;
          case "104":
            prefix = "621661";
            break;
          case "0303":
            prefix = "622666";
            break;
          case "305":
            prefix = "622622";
            break;
          case "0306":
            prefix = "622556";
            break;
          case "0308":
            prefix = "622588";
            break;
          case "0410":
            prefix = "622155";
            break;
          case "302":
            prefix = "622689";
            break;
          case "304":
            prefix = "622630";
            break;
          case "309":
            prefix = "622908";
            break;
          case "310":
            prefix = "621717";
            break;
          case "315":
            prefix = "622323";
            break;
          case "316":
            prefix = "622309";
            break;
          default:
        }

        for (var j = 0; j < 13; j++) {
          prefix = prefix + Math.floor(Math.random() * 10);
        }

        // console.log(prefix);
        this.res.bank = prefix;
        // return prefix;
      },
      // 生成随机手机号
      getMoble () {
        var prefixArray = new Array('135', '136', '137', '138', '139', '150', '151', '152', '157', '158', '159', '182', '183', '187', '188', '198', '130', '131', '132', '155', '156', '186', '181', '189');
        var i = parseInt(10 * Math.random());
        var prefix = prefixArray[i];
        for (var j = 0; j < 8; j++) {
          prefix = prefix + Math.floor(Math.random() * 10);
        }
        this.res.phone = prefix;
        // return prefix;
      },
      handleCopy(text, event) {
        clip(text, event)
      }
    }
  }
</script>

<style lang="less" scoped="scoped">
  .create-china-id-card {
    height: 100%;
    width: 100%;
    padding: 0;
    /*display: flex;
    justify-content: center;
    align-items: center;*/
    /*background-color: #555;*/

    .container {
      padding: 10px 20px;
      width: 100%;
      height: 100%;
      background-color: #fff;
      /*border-radius: 10px;
      box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.2);*/

      .res-item {
        margin: 0 0 15px 0;

        .res-button {
          margin: 0 0 0 5px;
        }
      }

    }

    p + p {
      margin-top: 1em;
    }
  }
</style>
